package fun.boomcat.luckyhe.mirai.plugin.command;

import fun.boomcat.luckyhe.mirai.plugin.bean.Reply;
import fun.boomcat.luckyhe.mirai.plugin.bean.ReplyState;
import fun.boomcat.luckyhe.mirai.plugin.bean.ReplyType;
import fun.boomcat.luckyhe.mirai.plugin.command.utils.ReplyHelpString;
import fun.boomcat.luckyhe.mirai.plugin.command.utils.ReplyCommandArgsHandler;
import fun.boomcat.luckyhe.mirai.plugin.command.utils.thread.ReplyWebThread;
import fun.boomcat.luckyhe.mirai.plugin.config.ConfigOperation;
import fun.boomcat.luckyhe.mirai.plugin.dbutils.ReplyListModifier;
import kotlin.Unit;
import kotlin.coroutines.Continuation;
import net.mamoe.mirai.console.command.CommandManager;
import net.mamoe.mirai.console.command.CommandOwner;
import net.mamoe.mirai.console.command.CommandSender;
import net.mamoe.mirai.console.command.RawCommand;
import net.mamoe.mirai.console.permission.Permission;
import net.mamoe.mirai.console.plugin.jvm.JavaPlugin;
import net.mamoe.mirai.contact.User;
import net.mamoe.mirai.message.data.MessageChain;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.IOException;
import java.util.*;

public class ReplyCommand extends RawCommand {
    private final JavaPlugin INSTANCE;

    public ReplyCommand(@NotNull CommandOwner owner, @NotNull String primaryName, @NotNull String[] secondaryNames, @NotNull String usage, @NotNull String description, @NotNull Permission parentPermission, boolean prefixOptional, JavaPlugin INSTANCE) {
        super(owner, primaryName, secondaryNames, usage, description, parentPermission, prefixOptional);
        this.INSTANCE = INSTANCE;
    }

    @Nullable
    @Override
    public Object onCommand(@NotNull CommandSender commandSender, @NotNull MessageChain messageChain, @NotNull Continuation<? super Unit> continuation) {
        int mcLen = messageChain.toArray().length;
        String commandPrefix = CommandManager.INSTANCE.getCommandPrefix();
        String primaryName = this.getPrimaryName();

        if (mcLen == 0) {
//            参数个数为0回复帮助

            commandSender.sendMessage(ReplyHelpString.helpStr(primaryName, getSecondaryNames()));
            return null;
        }

//        首个参数为操作
        String operation = messageChain.get(0).toString();

        switch (operation.toLowerCase()) {
            case "add":
            case "添加":
//                添加回复

                try {
                    onAddReply(
                            Arrays.copyOfRange(messageChain.toArray(), 1, mcLen),
                            commandSender,
                            commandPrefix,
                            primaryName
                    );
                } catch (IOException e) {
                    e.printStackTrace();
                }
                break;
            case "del":
            case "删除":
//                删除回复

                try {
                    onDelReply(
                            Arrays.copyOfRange(messageChain.toArray(), 1, mcLen),
                            commandSender,
                            commandPrefix,
                            primaryName
                    );
                } catch (IOException e) {
                    e.printStackTrace();
                }
                break;
            case "delid":
            case "回复号删除":
//                通过回复号删除回复

                onDelReplyById(
                        Arrays.copyOfRange(messageChain.toArray(), 1, mcLen),
                        commandSender,
                        commandPrefix,
                        primaryName
                );
                break;
            case "list":
            case "我的":
//                查看用户添加的回复

                onShowMyReply(commandSender, commandPrefix, primaryName, mcLen >= 2 && messageChain.get(1).toString().equals("-d"));
                break;
            default:
                commandSender.sendMessage("有奇怪的参数，" + commandPrefix + primaryName + "查看帮助");
                return null;
        }

        return null;
    }

    public Reply getReplyObjectFromCommand(Object[] args, CommandSender commandSender, String commandPrefix, String primaryName, String flag) {
//        add与del指令都需要获取reply对象，因此抽象为方法，以flag作为判断

        if (args.length == 0) {
            switch (flag) {
                case "add":
                    commandSender.sendMessage(ReplyHelpString.addHelpStr(primaryName, getSecondaryNames()));
                    commandSender.sendMessage(ReplyHelpString.addExampleStr(primaryName));
                    break;
                case "del":
                    commandSender.sendMessage(ReplyHelpString.delHelpStr(primaryName, getSecondaryNames()));
                    commandSender.sendMessage(ReplyHelpString.delExampleStr(primaryName));
                    break;
            }
            return null;
        }

        if (args.length != 6) {
//            参数为6个，不信可以数一下
            commandSender.sendMessage("奇怪的参数个数，" + commandPrefix + primaryName + "查看帮助");
            return null;
        }

//        从数据库获取该条回复
        Map<String, Object> replyMap = null;
        User user = commandSender.getUser();

        try {
            replyMap = ReplyCommandArgsHandler.getArgsMap(args);
        } catch (IllegalArgumentException e) {
            commandSender.sendMessage("奇怪的错误：" + e.toString() + "， " + commandPrefix + primaryName + "查看帮助");
            return null;
        } catch (IndexOutOfBoundsException e) {
            commandSender.sendMessage("奇怪的参数缺失，" + commandPrefix + primaryName + "查看帮助");
            return null;
        } catch (Exception e) {
            commandSender.sendMessage("错误：" + e.toString());
            return null;
        }

//        生成属性
        ReplyType rtype = (ReplyType) replyMap.get("type");
        String keyword = (String) replyMap.get("keyword");
        String reply = (String) replyMap.get("reply");

        long userId = user != null ? user.getId() : 0;

//        返回对象
        return new Reply(
                userId,
                rtype,
                keyword,
                reply,
                ReplyState.AUDITING
        );
    }

    public void onAddReply(Object[] args, CommandSender commandSender, String commandPrefix, String primaryName) throws IOException {

        Reply newReply = getReplyObjectFromCommand(args, commandSender, commandPrefix, primaryName, "add");
        if (newReply == null) {
//            newReply出现错误时为null

            return;
        }

//        获取同样内容的回复数量
        int sameReplyCount = ReplyListModifier.getSameReplyCount(newReply);
        if (sameReplyCount != 0) {
            commandSender.sendMessage("已存在相同数据条目");
            return;
        }

//        插入
        int res = ReplyListModifier.insertOneReply(newReply);

        if (res == 1) {
            StringBuilder sb = new StringBuilder();
            sb.append("回复插入成功，请等待管理员审核。\n");
            sb.append("类型：").append(newReply.getType().getName()).append("\n");
            sb.append("关键字：\n").append(newReply.getKeyword()).append("\n");
            sb.append("回复/替换内容：\n").append(newReply.getReply());
            commandSender.sendMessage(sb.toString());
        }
    }

    public void onDelReply(Object[] args, CommandSender commandSender, String commandPrefix, String primaryName) throws IOException {
        Reply reply = getReplyObjectFromCommand(args, commandSender, commandPrefix, primaryName, "del");
        if (reply == null) {
            return;
        }

        int res = ReplyListModifier.delOneReply(reply);
        if (res == 0) {
            commandSender.sendMessage("无该数据条目");
            return;
        } else {
            StringBuilder sb = new StringBuilder();
            sb.append("回复删除成功。\n");
            sb.append("类型：").append(reply.getType().getName()).append("\n");
            sb.append("关键字：\n").append(reply.getKeyword()).append("\n");
            sb.append("回复/替换内容：\n").append(reply.getReply());
            commandSender.sendMessage(sb.toString());
        }
    }

    public void onDelReplyById(Object[] args, CommandSender commandSender, String commandPrefix, String primaryName) {
//        通过回复号删除回复

        if (args.length == 0) {
            commandSender.sendMessage(ReplyHelpString.delByIdHelpStr(primaryName));
            return;
        }

        Set<Integer> ids = new HashSet<>();

        try {
            for (Object replyId : args) {
                ids.add(Integer.parseInt(replyId.toString()));
            }
        } catch (Exception e) {
            commandSender.sendMessage("错误：" + e.toString());
            return;
        }

        try {
            StringBuilder sb = new StringBuilder();
            User user = commandSender.getUser();
            long qq = user != null ? user.getId() : 0;
            for (Integer id : ids) {
                Reply reply = ReplyListModifier.selectReplyById(id);
                if (reply.getQq() != qq) {
                    commandSender.sendMessage("对于回复号为" + id + "的状态修改失败了，可能是不存在该条目或其它意外所致，这些回复号已删除完成：" + sb.toString());
                    return;
                }
                int res = ReplyListModifier.delOneReplyById(id);
                if (res == 0) {
                    commandSender.sendMessage("对于回复号为" + id + "的状态修改失败了，可能是不存在该条目或其它意外所致，这些回复号已删除完成：" + sb.toString());
                    return;
                }
                sb.append(id).append(" ");
            }
        } catch (Exception e) {
            commandSender.sendMessage("奇怪的错误：" + e.toString());
            return;
        }

        commandSender.sendMessage("指定回复已删除");
    }

    public void onShowMyReply(CommandSender commandSender, String commandPrefix, String primaryName, boolean hasHideDeleted) {
//        获取用户自身添加的回复

        User user = commandSender.getUser();
        long userId = user != null ? user.getId() : 0;

        try {
//            交由web显示

            ReplyWebThread.showUserRepliesWeb(userId, commandSender, hasHideDeleted);
            Map<String, String> webMap = ConfigOperation.getWebsiteInifo();
            String host = webMap.get("host");
            int port = Integer.parseInt(webMap.get("port"));

            String res = "点击查看： http://" + host + ":" + port + "\n公用链接，在下一次查询时会覆盖本次内容";
            if (!hasHideDeleted) {
//                提示用户使用-d参数可过滤已删除回复
                res += "\n/reply list -d为不显示已删除条目";
            }
            commandSender.sendMessage(res);
        } catch (IOException e) {
            commandSender.sendMessage("获取失败：" + e.toString());
        }
    }
}
